package com.sita.tboard.ui.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.View;

import com.sita.bike.R;

/**
 * 一个类似仪表盘样式的渐变进度条
 *
 * @author luoyanfeng
 */
public class GradientProgressBar extends View {
    private int DEFAULT_STROKE_WIDTH = 50;
    private int DEFAULT_ARC_ANGLE = 2;
    private int DEFAULT_GAP_ANGLE = 3;
    private int DEFAULT_SWEEP_ANGLE = 250;
    private int DEFAULT_ARC_COLOR = getResources().getColor(R.color.finestBlack20);
    private int DEFAULT_START_COLOR = getResources().getColor(R.color.c_80e2b1);
    private int DEFAULT_MIDDLE_COLOR = getResources().getColor(R.color.c_77d0ed);
    private int DEFAULT_END_COLOR = getResources().getColor(R.color.c_7c6dfa);
    /**
     * 进度格子的画笔
     */
    private Paint arcPaint;
    /**
     * 进度弧的绘制区域
     */
    private RectF arcRect = new RectF();
    /**
     * 弧的宽度
     */
    private int strokeWidth;
    /**
     * 进度格子的弧度
     */
    private int arcAngle;
    /**
     * 间隔的弧度
     */
    private int gapAngle;
    /**
     * 要显示的进度
     */
    private int progress;
    /**
     * 进度格子的颜色
     */
    private int arcColor;
    /**
     * 最大进度
     */
    private int max;
    /**
     * 弧度
     */
    private int sweepAngle;
    /**
     * 起始角度
     */
    private int startAngle;
    /**
     * 起点颜色
     */
    private int progressStartColor;
    /**
     * 中点颜色
     */
    private int progressMiddleColor;
    /**
     * 结束颜色
     */
    private int progressEndColor;
    /**
     * 进度格子的数量
     */
    private int arcCount;
    /**
     * 进度的画笔
     */
    private Paint progressPaint;
    /**
     * 是否在执行动画
     */
    private boolean isAnimating = false;
    /**
     * 间隔时间
     */
    private int sleepTimeMax = 90;
    /**
     * 进度当前绘制数量
     */
    private int progressDrawCount;
    /**
     * 渐变
     */
    private LinearGradient linearGradient;

    public GradientProgressBar(Context context) {
        this(context, null);
    }

    public GradientProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public GradientProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        final TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.GradientProgressBar, defStyleAttr, 0);
        initAttrs(attributes);
        attributes.recycle();

        initPaint();

        startAngle = -90 - sweepAngle / 2;
        arcCount = 1 + sweepAngle / (arcAngle + gapAngle);
        max = sweepAngle;
    }

    /**
     * 初始化参数
     *
     * @param attributes
     */
    private void initAttrs(TypedArray attributes) {
        strokeWidth = attributes.getInt(R.styleable.GradientProgressBar_gpb_stroke_width, DEFAULT_STROKE_WIDTH);
        arcAngle = attributes.getInt(R.styleable.GradientProgressBar_gpb_arc_angle, DEFAULT_ARC_ANGLE);
        gapAngle = attributes.getInt(R.styleable.GradientProgressBar_gpb_gap_angle, DEFAULT_GAP_ANGLE);
        arcColor = attributes.getInt(R.styleable.GradientProgressBar_gpb_arc_color, DEFAULT_ARC_COLOR);
        sweepAngle = attributes.getInt(R.styleable.GradientProgressBar_gpb_sweep_angle, DEFAULT_SWEEP_ANGLE);
        progressStartColor = attributes.getColor(R.styleable.GradientProgressBar_gpb_start_color, DEFAULT_START_COLOR);
        progressMiddleColor = attributes.getColor(R.styleable.GradientProgressBar_gpb_middle_color, DEFAULT_MIDDLE_COLOR);
        progressEndColor = attributes.getColor(R.styleable.GradientProgressBar_gpb_end_color, DEFAULT_END_COLOR);
    }

    /**
     * 初始化画笔
     */
    private void initPaint() {
        arcPaint = new Paint();
        arcPaint.setColor(arcColor);
        arcPaint.setStyle(Paint.Style.STROKE);
        arcPaint.setAntiAlias(true);
        arcPaint.setStrokeWidth(strokeWidth);

        progressPaint = new Paint();
        progressPaint.setStyle(Paint.Style.STROKE);
        progressPaint.setAntiAlias(true);
        progressPaint.setStrokeWidth(strokeWidth);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //初始化渐变shader
        if (linearGradient == null) {
            linearGradient = new LinearGradient(0, 0, getWidth(), 0, new int[]{progressStartColor, progressMiddleColor, progressEndColor}, null, Shader.TileMode.CLAMP);
            progressPaint.setShader(linearGradient);
        }
        //设定弧绘制区域
        arcRect.set(strokeWidth, strokeWidth, getWidth() - strokeWidth, getHeight() - strokeWidth);
        int angle = startAngle;
        for (int i = 0; i < arcCount; i++) {
            if (i < getDrawCount()) {
                canvas.drawArc(arcRect, angle, arcAngle, false, progressPaint);
            } else {
                canvas.drawArc(arcRect, angle, arcAngle, false, arcPaint);
            }
            angle += (arcAngle + gapAngle);
        }
    }

    /**
     * 设置进度
     *
     * @param progress
     */
    public void setProgress(int lastprogress, int progress) {
        if (progress > max || progress < 0) {
            throw new IllegalArgumentException("illegal progress");
        }
        this.progress = progress;
        //开始动画
        if (!isAnimating) {
            new ProgressAnimTask(lastprogress).execute();
        }
    }

    /**
     * 获取当前应绘制进度数量
     *
     * @return
     */
    public int getDrawCount() {
        return progressDrawCount;
    }

    /**
     * 设置当前应绘制进度数量
     *
     * @param count
     */
    public void setDrawCount(int count) {
        progressDrawCount = count;
    }

    /**
     * 获取动画中所需休眠时间
     *
     * @param cur
     * @param total
     * @return
     */
    private long getSleepTime(int cur, int total) {
        return (sleepTimeMax / total) * cur;
    }

    /**
     * 动画的异步执行任务
     */
    class ProgressAnimTask extends AsyncTask<Void, Integer, Void> {
        public int startcount;
        private int drawCount;

        public ProgressAnimTask(int lastcount) {
            this.startcount = lastcount;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            isAnimating = true;
            drawCount = progress / (max / arcCount);
        }

        @Override
        protected Void doInBackground(Void... params) {
//            int count = 1;
            int count = startcount;
            while (count <= drawCount) {
                onProgressUpdate(count++);
                try {
//                    Thread.sleep(getSleepTime(count, drawCount));
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            setDrawCount(values[0]);
            postInvalidate();
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            isAnimating = false;
        }
    }
}
